package logica.pessoa;


import java.util.ArrayList;

import logica.util.Endereco;




/**
 * Classe Pessoa
 * 
 * @authr Jose Arthur Morais (Tabira)
  *@since 15/10/2010
 *
 */
public class Pessoa {

	private String nome;
	private String telefone;
	private String email;
	private Endereco endereco;
	
	/**
	 * Controi um objeto pessoa
	 * 
	 * @param String nome
	 * @param String telefone
	 * @param String email
	 * @param Endereco endereco
	 * 
	 * @throws Exception nome invalido: o nome eh considerado invalido se naum possuir caracteres 
	 * \n se conter numero 
	 * \n se for menor que 8 caracteres
	 * @throws Exception telefone invalido: o telefone eh considerado invalido se naum possuir o formato (ii) iiiiiiii 
	 * \n e i tem que ser um digito
	 * @throws Exception email invalido: o email eh considerado invalido se naum possuir a formatacao ---@---.com.**,
	 * \n onde --- sao escolhidos pelo usuario e as ** representam a nacionalidade, que tem que ter dois caracteres
	 * \ncaso nao possua nacionalidade a formatacao ---@---.com tambem eh aceito
	 * \ncaso o endereco seja um objeto nulo
	 * 
	 *  @see  Usuario 
	 *  @see Cliente
	 *  @see Gerente
	 *  @see Funcionario
	 *  @see PessoaJuridica
	 *  
	 */
	public Pessoa(String nome, String telefone, String email, Endereco endereco) throws Exception{
		
		this.nome = nome;
		
		setTelefone(telefone);
		
		setEmail(email);
		
		setEndereco(endereco);
		
		
	}
	
	/**
	 * consulta o endereco da Pessoa
	 * @return Endereco endereco
	 */
	public Endereco getEndereco() {
		return endereco;
	}

	/**
	 * Muda o endereco da Pessoa
	 * @param Endereco endereco
	 */
	public void setEndereco(Endereco endereco) throws Exception {
		if (endereco == null) {
			throw new Exception("Endereco invalido.");
		}
		this.endereco = endereco;
	}
	
	/**
	 * consulta o telefone da Pessoa 
	 * @return String telefone
	 */
	public String getTelefone() {
		return telefone;
	}

	/**
	 * Muda o telefone da Pessoa
	 * @param String telefone
	 * @throws Exception  telefone invalido: o telefone eh considerado invalido se naum possuir o formato (ii) iiiiiiii onde i tem que ser um digito
	 */
	public void setTelefone(String telefone) throws Exception {
		
		if (telefone != null)
			validaTelefone(telefone);
		
		this.telefone = telefone;
	}

	/**
	 * Consulta o nome da pessoa
	 * @return String nome
	 */
	public String getNome() {
		return nome;
	}
	
	/**
	 * Muda o nome da pessoa
	 * @param String nome
	 * @throws Exception nome invalido: o nome eh considerado invalido se eh nulo, vazio ou possui algum digito.
	 */
	public void setNome(String nome) throws Exception {
		if(validaNome(nome)) {
			this.nome = nome;
		}
		throw new Exception("Nome invalido.");
	}

	/**
	 * Consulta o email da pessoa
	 * @return String email
	 */
	public String getEmail() {
		return email;
	}

	/**
	 * Muda o email da pessoa
	 * @param String email
	 * @throws Exception  email invalido: o email eh considerado invalido se naum possuir a formatacao ---@---.com.**, onde --- sao escolhidos pelo usuario e as ** representam a nacionalidade que tem que ter dois caracteres
	 * caso naum possua nacionalidade a formatacao ---@---.com tambem eh aceita 
	 * @throws Exception email eh individual
	 */
	public void setEmail(String email) throws Exception {
		
		if (email != null)
			validaEmail(email);
		
		this.email = email;
	}

	/**
	 * Testa as condicoes para telefone e lanca excessao se necessario
	 * @param String telefone
	 * @throws Exception telefone invalido: o telefone eh considerado invalido se naum possuir o formato (ii) iiiiiiii onde i tem que ser um digito
	 */
	public static void validaTelefone(String telefone) throws Exception {
		try {
			
			String dddEscolhido = telefone.split(" ")[0]; 

			dddEscolhido = dddEscolhido.replace("(", "").replace(")", "");
			
			String numero = telefone.split(" ")[1];    //se o " " nao existir lanca excessao

			if (numero.length() != 8  || ! hasDDD( dddEscolhido ) || telefone.length() != 13)   //testa se numero tem 8 digitos, se o ddd eh valido e se o tamanho do telefone eh invalido
				throw new Exception ("telefone invalido");
			
			Integer.parseInt(numero);  //se naum conseguir essa transformacao eh pq naum tem apenas numero, ai lanca excessao
		} 
		catch (Exception e) {
			throw new Exception ("telefone invalido");
		}
	}

	/**
	 * Verifica validade do nome e lanca excessao caso seja necessario
	 * @param String nome
	 * @throws Exception nome invalido: o nome eh considerado invalido se naum possuir caracteres ou se conter numero
	 * @throws Exception nome eh individual
	 */
	public static boolean validaNome(String nome) {
		
		if (nome == null )
			return false;
		
		if (nome.replace(" ","").length() < 8)
			return false;
		
		if (stringTemDigito(nome))
			return false;
		
		return true;
		
		
	}

	/**
	 * Testa condicoes para email e lanca excessao se for necessario
	 * @param String email
	 * @throws Exception  email invalido: o email eh considerado invalido se naum possuir a formatacao ---@---.com.**, onde --- sao escolhidos pelo usuario e as ** representam a nacionalidade que tem que ter dois caracteres
	 * caso naum possua nacionalidade a formatacao ---@---.com tambem eh aceita 
	 * @throws Exception email deve ser individual
	 */
	public static void validaEmail(String email)throws Exception{
		
		try{
			//antes do @
			
			String emailDivididoEmArroba []= email.split("@");

			String emailAntesDoArroba = emailDivididoEmArroba[0];
		
			if (emailDivididoEmArroba.length != 2 || emailAntesDoArroba.trim().isEmpty())  //testando se email tem exatamente um @ e se existe algo antes dele
				throw new Exception ("email invalido");
		
			
			
			
			//depois do @
			
			
			String eDDADPP [] = emailDivididoEmArroba[1].replace(".","#").split("#");  // eDDADPP = emailDepoisDoArrobaDivididoPeloPonto
			
			if (eDDADPP[0].trim().isEmpty() || ! eDDADPP[1].equals("com"))
				throw new Exception ("email invalido");
			
			if (eDDADPP.length == 3)               //email pode ter nacionalidade no final
				if (eDDADPP[2].length() != 2)				
					throw new Exception ("email invalido");

			if (eDDADPP.length > 3)
				throw new Exception ("email invalido");		
			
		}
		
		catch (Exception e) {
			throw new Exception ("email invalido");
		}
		
		
	}

	/**
	 * Verifica validade de DDD
	 * @param String dddEscolhido
	 * @return true se o ddd existi
	 */
	private static boolean hasDDD(String dddEscolhido){
		
		String ddd [] = {"11", "12", "13", "14", "15", "16", "17", "18", "19", "21", "22", "24", "27", "28", "31", "32", "33", "34", "37", "38", "41", "42", "43", "44", "45", "46", "47", "48", "49", "51", "53", "54", "55", "61", "62", "63", "64", "65", "66", "67", "68", "69", "71", "73", "74", "75", "77", "79", "81", "82", "83", "84", "85", "86", "87", "88", "89", "91", "92", "93", "94", "95", "96", "97", "98", "99"};
		ArrayList <String> DDD = new ArrayList <String> ();
		
		for (int i =0; i < ddd.length; i++){
			DDD.add(ddd[i]);
		}
		
		return DDD.contains(dddEscolhido);
	}

	/**
	 * Analisa string para verificar existencia apenas de digito
	 * @param String string
	 * @return boolean true se a string so possuir digito
	 */
	public static boolean stringSoTemDigito(String string){

		for (int i =0; i < string.length(); i++){
			char caracter = string.charAt(i);
		
			if ( ! Character.isDigit(caracter))
				return false;
		}	
		
		return true;
		
	}
	
	/**
	 * Analisa string para verificar existencia de digito
	 * @param String string
	 * @return boolean true se a string possui digito
	 */
	public static boolean stringTemDigito(String string){
		
		for (int i =0; i < string.length(); i++){
			
			char caracter = string.charAt(i);
			
			if ( Character.isDigit(caracter))
				return true;
		}	
		
		return false;
		
	}

	/**
	 * Analisa string para verificar se eh vazia
	 * @param String string
	 * @return boolean true se for vazia
	 */
	public static boolean stringEhVazio(String string){
		return string.trim().isEmpty();
	}

	/**
	 * Representa Pessoa em forma de String
	 * 
	 *  @return String Pessoa
	 */
	@Override public String toString(){
		return "Nome: "+ nome;
	}
	
}










































